using System;
using System.Collections.Generic;
using FireStarter.Base;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.Test.BO;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic
{
    [TestFixture]
    public class TestCreateUIGridFilterDefFromDomainModel
    {
        #region Setup/Teardown

        [TestFixtureSetUp]
        public virtual void TestFixtureSetup()
        {
            TestUtilsLogic.SetupFixture();
        }

        [SetUp]
        public virtual void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        [TearDown]
        public virtual void TearDownTest(){}
        #endregion

        [Test]
        public void Test_CreateFilterProp_WhenPropNull_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator(null);
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            try
            {
                gridFilterCreator.CreateFilterProp(null);
                Assert.Fail("expected ArgumentNullException");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("property", ex.ParamName);
            }
        }
        [Test]
        public void Test_CreateFilterProp_WhenPropClassNull_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMProperty();
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator(null);
            //---------------Assert Precondition----------------
            Assert.IsNull(property.Class);
            //---------------Execute Test ----------------------
            try
            {
                gridFilterCreator.CreateFilterProp(property);
                Assert.Fail("expected HabaneroArgumentException");
            }
                //---------------Test Result -----------------------
            catch (HabaneroArgumentException ex)
            {
                StringAssert.Contains("You cannot create a UIGridFilterProp for a property that is not associated with a class", ex.Message);
            }
        }
        [Test]
        public void Test_CreateFilterProp_WhenPropTypeIsNull_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            property.PropertyType = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(property.PropertyType);
            //---------------Execute Test ----------------------
            try
            {
                gridFilterCreator.CreateFilterProp(property);
                Assert.Fail("expected HabaneroArgumentException");
            }
                //---------------Test Result -----------------------
            catch (HabaneroArgumentException ex)
            {
                StringAssert.Contains("You cannot create a UIGridFilterProp for a property that is not associated with a PropertyType", ex.Message);
            }
        }
        [Test]
        public void Test_CreateFilterProp_WhenClassSolutionNull_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMProperty();
            property.Class = TestUtilsDMClass.CreateUnsavedDefaultDMClass();
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            Assert.IsNull(property.Class.Solution);
            //---------------Execute Test ----------------------
            try
            {
                gridFilterCreator.CreateFilterProp(property);
                Assert.Fail("expected HabaneroArgumentException");
            }
                //---------------Test Result -----------------------
            catch (HabaneroArgumentException ex)
            {
                StringAssert.Contains("You cannot create a UIGridFilterProp for a property that is not associated with a Solution", ex.Message);
            }
        }

        [Test]
        public void Test_CreateFilterProp_WhenString_ShouldHaveStringFilterTextBox()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            property.OrdinalPosition = 3;
            TestUtilsDMProperty.SetDMPropStringType(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsString(property);
            Assert.IsNotNull(property.OrdinalPosition);
            Assert.Greater(property.OrdinalPosition, 0);
            TestUtilsShared.AssertStringNotEmpty(property.Description, "Property Descripton");
            TestUtilsShared.AssertStringNotEmpty(property.PropertyName, "Property Name");
            TestUtilsShared.AssertStringNotEmpty(property.DisplayName, "Display Name");
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            Assert.IsNotNull(filterProp);
            Assert.IsNotNull(filterProp.PropertyName);
            Assert.IsFalse(filterProp.Generated.GetValueOrDefault());
            Assert.AreEqual(property.DisplayName, filterProp.LabelText, "filterProp.LabelText");
            Assert.AreEqual(property.OrdinalPosition, filterProp.OrdinalPosition);
            Assert.AreEqual(property.PropertyName, filterProp.PropertyName);
            AssertControlTypeIsStringFilterTextBox(filterProp.UIGridFilterType);
            Assert.IsFalse(filterProp.Generated.GetValueOrDefault());
            TestUtilsShared.AssertStringEmpty(filterProp.ToolTipText, "filterProp.ToolTipText", "The tool tip text should not be set it will default to the Property Description");

            Assert.AreEqual(FilterClauseOperator.OpLike, filterProp.FilterClauseOp);
        }

        public static void AssertControlTypeIsStringFilterTextBox(UITypeDefinition controlType)
        {
            Assert.IsNotNull
                (controlType, "The UITypeDefinition should be StringTextBoxFilter and Cannot be null");
            Assert.AreEqual(BOBroker.GetMapperAssemblyName(), controlType.AssemblyName);
            Assert.AreEqual("StringTextBoxFilter", controlType.TypeName);
        }

        private static void AssertControlTypeIsBoolCheckBoxFilter(UITypeDefinition controlType)
        {
            Assert.IsNotNull
                (controlType, "The UITypeDefinition should be BoolCheckBoxFilter and Cannot be null");
            Assert.AreEqual(BOBroker.GetMapperAssemblyName(), controlType.AssemblyName);
            Assert.AreEqual("BoolCheckBoxFilter", controlType.TypeName);
        }

        private static void AssertControlTypeIsStringComboBoxFilter(UITypeDefinition controlType)
        {
            Assert.IsNotNull
                (controlType, "The UITypeDefinition should be StringComboBoxFilter and Cannot be null");
            Assert.AreEqual(BOBroker.GetMapperAssemblyName(), controlType.AssemblyName);
            Assert.AreEqual("StringComboBoxFilter", controlType.TypeName);
        }

        private static void AssertControlTypeIsDateRangeComboBoxFilter(UITypeDefinition controlType)
        {
            Assert.IsNotNull
                (controlType, "The UITypeDefinition should be DateRangeComboBoxFilter and Cannot be null");
            Assert.AreEqual(BOBroker.GetMapperAssemblyName(), controlType.AssemblyName);
            Assert.AreEqual("DateRangeComboBoxFilter", controlType.TypeName);
        }


        [Test]
        public void Test_CreateFilterProp_WhenInt_ShouldHaveStringFilterTextBox()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropIntType(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsInt(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            Assert.IsNotNull(filterProp);
            Assert.IsNotNull(filterProp.PropertyName);
            Assert.AreEqual(property.PropertyName, filterProp.PropertyName);

            AssertControlTypeIsStringFilterTextBox(filterProp.UIGridFilterType);
            Assert.AreEqual(FilterClauseOperator.OpLike, filterProp.FilterClauseOp);
        }

        [Test]
        public void Test_CreateTwoFormFilterPropDefs_String_ShouldBothHaveSameControlType()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropStringType(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsString(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            UIGridFilterProp filterProp2 = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            Assert.AreNotSame(filterProp, filterProp2);
            Assert.AreSame(filterProp.UIGridFilterType, filterProp2.UIGridFilterType);
            AssertControlTypeIsStringFilterTextBox(filterProp.UIGridFilterType);
        }

        [Test]
        public void Test_CreateFilterProp_Bool_ShouldBeBoolCheckBoxFilter()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropBooleanType(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);

            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsBool(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            Assert.AreEqual(property.PropertyName, filterProp.PropertyName);
            AssertControlTypeIsBoolCheckBoxFilter(filterProp.UIGridFilterType);
            Assert.AreEqual(FilterClauseOperator.OpEquals, filterProp.FilterClauseOp);
        }

        [Test]
        public void Test_CreateTwoFormFilterPropDefs_Boolean_ShouldBothHaveSameControlType()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropBooleanType(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsBool(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            UIGridFilterProp filterProp2 = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            Assert.AreNotSame(filterProp, filterProp2);
            Assert.AreSame(filterProp.UIGridFilterType, filterProp2.UIGridFilterType);
            AssertControlTypeIsBoolCheckBoxFilter(filterProp.UIGridFilterType);
        }

        [Test]
        public void Test_CreateFilterProp_Lookup_ShouldBeStringComboBoxFilter()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropWithLookupList(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsLookup(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            AssertControlTypeIsStringComboBoxFilter(filterProp.UIGridFilterType);
            Assert.AreEqual(FilterClauseOperator.OpEquals, filterProp.FilterClauseOp);

        }

        [Test]
        public void Test_CreateTwoFormFilterPropDefs_Lookup_ShouldBothHaveSameControlType()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropWithLookupList(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsLookup(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            UIGridFilterProp filterProp2 = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            Assert.AreNotSame(filterProp, filterProp2);
            Assert.AreSame(filterProp.UIGridFilterType, filterProp2.UIGridFilterType);
            AssertControlTypeIsStringComboBoxFilter(filterProp.UIGridFilterType);
        }

        [Test]
        public void Test_CreateFilterProp_DateTime_ShouldBeDateRangeComboBoxFilter()
        {
            //---------------Set up test pack-------------------
            SolutionCreator creator = new SolutionCreator();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedDefaultDMPropertyWithClass(creator.CreateSolution());
            TestUtilsDMProperty.SetDMPropWithDateTime(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            UICreatorTestUtils.AssertPropertyTypeIsDateTime(property);
            //---------------Execute Test ----------------------
            UIGridFilterProp filterProp = gridFilterCreator.CreateFilterProp(property);
            //---------------Test Result -----------------------
            AssertControlTypeIsDateRangeComboBoxFilter(filterProp.UIGridFilterType);
            Assert.AreEqual(FilterClauseOperator.OpEquals, filterProp.FilterClauseOp);
        }

        [Test]
        public void Test_CreateUIGridFilter_OneProperty_ShouldHaveAppropriateUIGridFilterProps()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = UICreatorTestUtils.CreateClassWithOneLookupProperty();
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) dmClass.Solution);
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass);
            Assert.AreEqual(1, dmClass.Properties.Count);
            //---------------Execute Test ----------------------
            UIGridFilter gridFilter = gridFilterCreator.CreateUIGridFilter(dmClass.Properties);
            //---------------Test Result -----------------------
            Assert.IsNotNull(gridFilter);
            Assert.AreEqual(1, gridFilter.UIGridFilterProps.Count);
            UIGridFilterProp filterProp = gridFilter.UIGridFilterProps[0];
            AssertControlTypeIsStringComboBoxFilter(filterProp.UIGridFilterType);
            Assert.IsFalse(gridFilter.Generated.Value);
            Assert.AreEqual("Search", gridFilter.FilterMode.ToString());
        }

        [Test]
        public void Test_CreateUIGridFilter_TwoProperty_ShouldHaveAppropriateUIGridFilterProps()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = UICreatorTestUtils.CreateClassWithOneLookupProperty();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            TestUtilsDMProperty.SetDMPropBooleanType(dmProperty);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) dmClass.Solution);
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass);
            Assert.AreEqual(2, dmClass.Properties.Count);
            //---------------Execute Test ----------------------
            UIGridFilter gridFilter = gridFilterCreator.CreateUIGridFilter(dmClass.Properties);
            //---------------Test Result -----------------------
            Assert.IsNotNull(gridFilter);
            gridFilter.UIGridFilterProps.Sort("OrdinalPosition", true, true);
            BusinessObjectCollection<UIGridFilterProp> fields = gridFilter.UIGridFilterProps;
            Assert.AreEqual(2, fields.Count);
            AssertControlTypeIsStringComboBoxFilter(fields[0].UIGridFilterType);
            AssertControlTypeIsBoolCheckBoxFilter(fields[1].UIGridFilterType);
        }

        [Test]
        public void Test_CreateUIGridFilter_TwoProperty_OneObjectID_ShouldHaveObjectIDControl()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = UICreatorTestUtils.CreateClassWithOneLookupProperty();
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            TestUtilsDMProperty.SetDMPropBooleanType(dmProperty);
            DMProperty property = dmClass.Properties.CreateBusinessObject();
            TestUtilsDMProperty.SetDMPropStringType(property);
            dmClass.CreateObjectIdentity(property);
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass);
            Assert.AreEqual(3, dmClass.Properties.Count);
            //---------------Execute Test ----------------------
            UIGridFilter gridFilter = gridFilterCreator.CreateUIGridFilter(dmClass.Properties);
            //---------------Test Result -----------------------
            Assert.IsNotNull(gridFilter);
            Assert.AreEqual(3, gridFilter.UIGridFilterProps.Count);
        }

        [Test]
        public void Test_CreateUIGridFilter_TwoProperty_OneKeepValuePrivate_ShouldHaveKeepvaluePrivateControl()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = UICreatorTestUtils.CreateClassWithOneLookupProperty();
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            TestUtilsDMProperty.SetDMPropBooleanType(dmProperty);
            DMProperty property = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            property.KeepValuePrivate = true;
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator((DMSolution) property.Class.Solution);
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass);
            Assert.AreEqual(3, dmClass.Properties.Count);
            Assert.IsTrue(property.KeepValuePrivate.Value);
            //---------------Execute Test ----------------------
            UIGridFilter gridFilter = gridFilterCreator.CreateUIGridFilter(dmClass.Properties);
            //---------------Test Result -----------------------
            Assert.IsNotNull(gridFilter);
            Assert.AreEqual(3, gridFilter.UIGridFilterProps.Count);
        }
        [Test]
        public void Test_CreateUIGridFilter_WhenPropertiesNull_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------
            UIGridFilterCreator gridFilterCreator = new UIGridFilterCreator(null);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                gridFilterCreator.CreateUIGridFilter((IList<DMProperty>)null);
                Assert.Fail("expected ArgumentNullException");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("properties", ex.ParamName);
            }
        }
    }

}